from abc import abstractmethod

from sam.util.dbUtil import DB, DEFAULT_PROCESS_DB_CONNECTION_CONFIG


class Db2Db(DB):
    def __init__(self, config=DEFAULT_PROCESS_DB_CONNECTION_CONFIG):
        super().__init__(config=config)
        self.db_read_stats = {"total": 0}

    def get_db_data_by_generator(self
                                 , table_name
                                 , where: str = None
                                 , column: list = None
                                 , column_str: str = None
                                 , batch_size: int = 10000
                                 , optional: str = "list"
                                 , distinct: bool = False
                                 , datetime_formatter: str = None
                                 , result_formatter=None
                                 , is_only_print_sql: bool = False
                                 , is_fixed_start: bool = False
                                 , is_need_check: bool = True
                                 ):
        if where and "status" in where:
            if not is_fixed_start:
                if is_need_check:
                    msg = "查询语句中使用了状态条件，但是没有查询固定开始位置"
                    raise RuntimeWarning(msg)
        elif is_fixed_start:
            if is_need_check:
                msg = "查询语句中固定了开始位置，但是查询条件中没有状态筛选条件"
                raise RuntimeWarning(msg)

        total_count = self.count(table_name, where=where, column=column, column_str=column_str, distinct=distinct)
        self.operate_record_stats["total"] = total_count
        self.logger.info(f"从数据库中查询到 共有 {total_count} 条数据要处理")
        max_count = total_count - 1 + batch_size
        _start = 0
        _end = _start + batch_size
        while _end <= max_count:
            # is_fixed_start == True 这种情况 适用于 被查询结果 可能允许被修改的情况
            if is_fixed_start:
                __start = 0
            else:
                __start = _start
            yield self.query(
                table_name
                , where=where
                , column=column
                , column_str=column_str
                , start=__start
                , limit=batch_size
                , optional=optional
                , distinct=distinct
                , datetime_formatter=datetime_formatter
                , result_formatter=result_formatter
                , is_only_print_sql=is_only_print_sql
            )
            _start += batch_size
            _end += batch_size

    def batch_handle_db_data_by_generator(self
                                          , table_name: str
                                          , where: str = None
                                          , column: list = None
                                          , column_str: str = None
                                          , batch_size: int = 5000
                                          , distinct: bool = False
                                          , datetime_formatter: str = None
                                          , optional: str = "list"
                                          , is_fixed_start: bool = False
                                          , is_need_check: bool = True
                                          ):
        loop = self.get_db_data_by_generator(
            table_name, where=where, column=column, column_str=column_str, batch_size=batch_size,
            distinct=distinct, optional=optional, is_fixed_start=is_fixed_start
            , datetime_formatter=datetime_formatter, is_need_check=is_need_check
        )
        while True:
            try:
                one_generator_return_list = next(loop)
                self._handle_one_generator_return_data(one_generator_return_list)
            except StopIteration:
                break

    @abstractmethod
    def _handle_one_generator_return_data(self, one_generator_return_list):
        pass
